package cn.edu.cug.cs.gtl.docsrv.txt.controller;

import cn.edu.cug.cs.gtl.docsrv.dict.exception.BaseException;
import cn.edu.cug.cs.gtl.docsrv.txt.service.TxtService;
import cn.edu.cug.cs.gtl.extractor.ShapeExtractor;
import cn.edu.cug.cs.gtl.mybatis.mapper.txt.TxtAll;
import cn.edu.cug.cs.gtl.mybatis.mapper.txt.TxtCatalog;
import cn.edu.cug.cs.gtl.mybatis.mapper.txt.TxtAll;
import cn.edu.cug.cs.gtl.mybatis.mapper.txt.TxtCatalog;
import cn.edu.cug.cs.gtl.mybatis.metadata.TxtUtils;
import cn.edu.cug.cs.gtl.mybatis.metadata.TxtUtils;
import cn.edu.cug.cs.gtl.protos.Document;
import cn.edu.cug.cs.gtl.protos.DocumentList;
import cn.edu.cug.cs.gtl.protos.Tree;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.protobuf.util.JsonFormat;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Envelope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

@Controller
@CrossOrigin
@RequestMapping("/api")
public class TxtController {

    @Autowired
    TxtService txtService;

    /**
     服务编号：9001
     服务名称：addTxt
     功能描述：单个本地Txt文件入库
     接口描述： /api/txt/addTxt
     传入参数：
     TxtAll  txt；前端传入TxtAll的JSON对象
     返回值：
     成功返回true , 否则返回false
     调用示例：
     */
    @PostMapping(value = "/txt/addTxt")
    public void addTxt(
            @RequestParam(value = "data") String data){
        try {
            TxtAll txtAll = JSON.parseObject(data,TxtAll.class);
            if(txtAll!=null)
                txtService.addTxt(txtAll);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     服务编号：9002
     服务名称：addTxts
     功能描述：多个本地TXT文件入库
     接口描述： /api/txt/ addTxts
     传入参数：
     List<TxtAll>  txts；前端传入TxtAll列表的JSON对象
     返回值：
     成功返回true , 否则返回false
     调用示例：
     */
    @PostMapping(value = "/txt/addTxts")
    public void addTxts(
            @RequestParam(value = "data") String data){
        try {
            TxtAllList txtAllList = JSON.parseObject(data,TxtAllList.class);
            if(txtAllList!=null)
                txtService.addTxts(txtAllList.getTxtAllList());
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     服务编号：9003
     服务名称：addFromRawDB
     功能描述：从原始数据库中提取指定类型的图形文件入库
     接口描述： /api/txt/addFromRawDB
     传入参数：
     String txtType   图形类型，文件后缀；
     返回值：
     成功返回true , 否则返回false
     调用示例：
     */
    @PostMapping(value = "/txt/addFromRawDB")
    public void addFromRawDB(@RequestParam(value = "txtType") String txtType){
        try {
            txtService.addFromRawDB();
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     服务编号：9004
     服务名称：getTxtByName
     功能描述：文本数据库中提取指定名称的文本文件
     接口描述： /api/txt/getTxtByName
     传入参数：
     String txtName   文本名称；
     返回值：
     List<TxtAll> txtAllList 的JSON字符串
     调用示例：
     */
    @GetMapping(value = "/txt/getTxtByName")
    public List<TxtAll> getTxtByName(@RequestParam(value = "txtName") String txtName){
        try {
            return txtService.getTxtByName(txtName);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     服务编号：7005
     服务名称：getTxtByEnTitle
     功能描述：图形数据库中提取指定英文名称的图形文件
     接口描述： /api/txt/ getTxtByEnTitle
     传入参数：
     String txtEnTitle ；
     返回值：
     List<TxtAll> txtAllList 的JSON字符串
     调用示例：
     */
    @GetMapping(value = "/txt/getTxtByEnTitle")
    public List<TxtAll> getTxtByEnTitle(@RequestParam(value = "txtEnTitle") String txtEnTitle){
        try {
            return txtService.getTxtByEnTitle(txtEnTitle);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     服务编号：7006
     服务名称：getTxtByCnTitle
     功能描述：图形数据库中提取指定中文名称的图形文件
     接口描述： /api/txt/ getTxtByCnTitle
     传入参数：
     String txtCnTitle ；
     返回值：
     List<TxtAll> txtAllList 的JSON字符串
     调用示例：
     */
    @GetMapping(value = "/txt/getTxtByCnTitle")
    public List<TxtAll> getTxtByCnTitle(@RequestParam(value = "txtCnTitle") String txtCnTitle){
        try {
            return txtService.getTxtByEnTitle(txtCnTitle);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7007
     服务名称：getTxtByInternalId
     功能描述：图形数据库中提取指定ID的图形文件
     接口描述： /api/txt/getTxtByInternalId
     传入参数：
     long txtInternalId；
     返回值：
     TxtAll  txt     ; TxtAll的JSON字符串
     调用示例：
     */
    @GetMapping(value = "/txt/getTxtByInternalId")
    public TxtAll getTxtByInternalId(@RequestParam(value = "txtInternalId") long txtInternalId){
        try {
            return txtService.getTxtByInternalId(BigDecimal.valueOf(txtInternalId));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7009
     服务名称：deleteTxtByInternalId
     功能描述：删除图形数据库中指定ID的图形
     接口描述： /api/txt/deleteTxtByInternalId
     传入参数：
     long internalId；
     返回值：
     成功返回true , 否则返回false
     调用示例：
     */
    @PostMapping(value = "/txt/deleteTxtByInternalId")
    public void deleteTxtByInternalId(@RequestParam(value = "txtInternalId") long txtInternalId){
        try {
            txtService.deleteTxtByInternalId(BigDecimal.valueOf(txtInternalId));
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 服务编号：7014
     * 服务名称：getTxtCatalogs
     * 功能描述：图形数据库中提取所有分类
     * 接口描述： /api/txt/getTxtCatalogs
     * 传入参数：
     * 返回值：
     * List<TxtCatalog> catalogs
     * 调用示例：
     */
    @GetMapping(value = "/txt/getTxtCatalogs")
    public List<TxtCatalog> getTxtCatalogs() {
        return txtService.getTxtCatalogs();
    }

    /**
     服务编号：7016
     服务名称：getDocumentByTxtInternalId
     功能描述：图形数据库中提取指定Txt文档
     接口描述： /api/txt/getDocumentByTxtInternalId
     传入参数：
     long txtInternalId
     返回值：
     Document doc;
     其中，每个Feature的GeoJSON字符串为Document的一个content；
     其他的不为空的字段为该Txt文档的元数据。
     调用示例：
     http://localhost:8090/api/txt/getDocumentByTxtInternalId?txtInternalId=3
     */
    @GetMapping(value = "/txt/getDocumentByTxtInternalId")
    public byte[] getDocumentByTxtInternalId(
            @RequestParam(value = "txtInternalId") long txtInternalId){
        try {
            Document d= txtService.getDocumentByTxtInternalId(BigDecimal.valueOf(txtInternalId));
            if(d!=null)
                return d.toByteArray();
            else
                return null;
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7017
     服务名称：addTxtDocument
     功能描述：单个本地Txt文件入库,采用Document传递
     接口描述： /api/txt/addTxtDocument
     传入参数：
     Document  txt；前端传入的和ShapAll对应的Document的字节数组
     返回值：
     成功返回true , 否则返回false
     调用示例：
     */
    @PostMapping(value = "/txt/addTxtDocument")
    public void addTxtDocument(@RequestBody  byte[] data){
        try {
            Document d = Document.parseFrom(data);
            if(d!=null){
                TxtAll txtAll = TxtUtils.convert(d);
                if(txtAll!=null)
                    txtService.addTxt(txtAll);
            }
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7018
     服务名称：addTxtDocuments
     功能描述：多个SHP文档入库
     接口描述： /api/txt/addTxtDocuments
     传入参数：
     DocumentList  txts；DocumentList的字节数组
     返回值：
     成功返回true , 否则返回false
     调用示例：
     */
    @PostMapping(value = "/txt/addTxtDocuments")
    public void addTxtDocuments(@RequestBody byte[] data){
        try {
            DocumentList dl = DocumentList.parseFrom(data);
            for(Document d:dl.getElementList()){
                if(d!=null){
                    TxtAll txtAll = TxtUtils.convert(d);
                    if(txtAll!=null)
                        txtService.addTxt(txtAll);
                }
            }
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }



    /**
     服务编号：7019
     服务名称：getDocumentsByTxtName
     功能描述：图形数据库中提取指定名称的图形文档
     接口描述： /api/txt/getDocumentsByTxtName
     传入参数：
     String  txtName；
     返回值：
     DocumentList  txts；DocumentList的字节数组；
     其中每个Document的Contents存放1至多个FeatureJSON
     调用示例：
     */
    @GetMapping(value = "/txt/getDocumentsByTxtName")
    public byte[] getDocumentsByTxtName(@RequestParam(value = "txtName") String txtName){
        try {
            List<TxtAll> txtAllList= txtService.getTxtByName(txtName);
            DocumentList.Builder documentListBuilder = DocumentList.newBuilder();
            for (TxtAll txtAll : txtAllList){
                Document doc = TxtUtils.convert(txtAll);
                documentListBuilder.addElement(doc);
            }
            return documentListBuilder.build().toByteArray();
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7020
     服务名称：getDocumentsByTxtEnTitle
     功能描述：图形数据库中提取指定英文名称的图形文件
     接口描述： /api/txt/getDocumentsByTxtEnTitle
     传入参数：
     String txtEnTitle ；
     返回值：
     DocumentList  txts；DocumentList的字节数组；
     其中每个Document的Contents存放1至多个FeatureJSON
     调用示例：
     */
    @GetMapping(value = "/txt/getDocumentsByTxtEnTitle")
    public byte[] getDocumentsByTxtEnTitle(@RequestParam(value = "txtEnTitle") String txtEnTitle){
        try {
            List<TxtAll> txtAllList= txtService.getTxtByEnTitle(txtEnTitle);
            DocumentList.Builder documentListBuilder = DocumentList.newBuilder();
            for (TxtAll txtAll : txtAllList){
                Document doc = TxtUtils.convert(txtAll);
                documentListBuilder.addElement(doc);
            }
            return documentListBuilder.build().toByteArray();
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7021
     服务名称：getDocumentsByTxtCnTitle
     功能描述：图形数据库中提取指定中文名称的图形文档
     接口描述： /api/txt/getDocumentsByTxtCnTitle
     传入参数：
     String txtCnTitle ；
     返回值：
     DocumentList  txts；DocumentList的字节数组；
     其中每个Document的Contents存放1至多个FeatureJSON
     调用示例：
     */
    @GetMapping(value = "/txt/getDocumentsByTxtCnTitle")
    public byte[] getDocumentsByTxtCnTitle(@RequestParam(value = "txtCnTitle") String txtCnTitle){
        try {
            List<TxtAll> txtAllList= txtService.getTxtByCnTitle(txtCnTitle);
            DocumentList.Builder documentListBuilder = DocumentList.newBuilder();
            for (TxtAll txtAll : txtAllList){
                Document doc = TxtUtils.convert(txtAll);
                documentListBuilder.addElement(doc);
            }
            return documentListBuilder.build().toByteArray();
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }




    /**
     服务编号：7023
     服务名称：getDocumentsByCatalogInternalId
     功能描述：图形数据库中提取指定分类ID的所有图形文档
     接口描述：/api/txt/getDocumentsByCatalogInternalId
     传入参数：
     long catalogInternalId
     返回值：
     DocumentList docList;
     其中，每个Feature的GeoJSON字符串为Document的一个content；
     其他的不为空的字段为该Txt文档的元数据。
     调用示例：
     http://localhost:8090/api/txt/getDocumentsByCatalogInternalId?catalogInternalId=3
     */
    @GetMapping(value = "/txt/getDocumentsByCatalogInternalId")
    public byte[] getDocumentsByCatalogInternalId(
            @RequestParam(value = "catalogInternalId") long catalogInternalId){
        try {
            DocumentList dl= txtService.getDocumentsByCatalogInternalId(BigDecimal.valueOf(catalogInternalId));
            if(dl!=null) {
                return dl.toByteArray();
            }
            else
                return null;
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7024
     服务名称：getCatalogTree
     功能描述：图形数据库中分类树
     接口描述：/api/txt/getCatalogTree
     传入参数：
     返回值：Tree   tree。
     调用示例：
     http://localhost:8090/api/txt/getCatalogTree
     */
//    @GetMapping(value = "/txt/getCatalogTree")
//    public byte[] getCatalogTree(){
//        try {
//            CatalogTree catalogTree = txtService.getCatalogTree();
//            if(catalogTree!=null){
//                Tree tree = catalogTree.cloneTree();
//                if(tree!=null)
//                    return tree.toByteArray();
//            }
//            return null;
//        } catch (Exception e) {
//            throw new BaseException(e.getMessage());
//        }
//    }

    /**
     服务编号：7025
     服务名称：getCatalogTreeJSON
     功能描述：图形数据库中分类树的JSON
     接口描述：/api/txt/getCatalogTreeJSON
     传入参数：
     返回值：Tree   tree 对于的JSON
     调用示例：
     http://localhost:8090/api/txt/getCatalogTreeJSON
     */
//    @GetMapping(value = "/txt/getCatalogTreeJSON")
//    public String getCatalogTreeJSON(){
//        try {
//            CatalogTree catalogTree = txtService.getCatalogTree();
//            if(catalogTree!=null){
//                Tree tree = catalogTree.cloneTree();
//                if(tree!=null){
//                    String sss = JsonFormat.printer().print(tree.toBuilder());
//                    return sss;
//                }
//            }
//            return null;
//        } catch (Exception e) {
//            throw new BaseException(e.getMessage());
//        }
//    }



    /**
     服务编号：7026
     服务名称：getTxtInternalIdsByCatalogInternalId
     功能描述：图形数据库中提取指定分类ID的所有图形文档的ID
     接口描述：/api/txt/getTxtInternalIdsByCatalogInternalId
     传入参数：
     long catalogInternalId
     返回值： String TxtInternalIds,
     JSONArray
     例如 "[1,2,3,4,5,6]"
     调用示例：
     http://localhost:8090/api/txt/getTxtInternalIdsByCatalogInternalId?catalogInternalId=3
     */
    @GetMapping(value = "/txt/getTxtInternalIdsByCatalogInternalId")
    public String getTxtInternalIdsByCatalogInternalId(
            @RequestParam(value = "catalogInternalId") long catalogInternalId){
        try {
            List<BigDecimal> ls = txtService.getTxtInternalIdsByCatalogInternalId(BigDecimal.valueOf(catalogInternalId));
            if(ls==null && ls.isEmpty()) return new String();

            int c = ls.size();
            long [] rs = new long[c];
            int i=0;
            for(BigDecimal b: ls) {
                rs[i] = b.longValue();
                ++i;
            }
            return JSONArray.toJSONString(rs);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }


    /**
     服务编号：7027
     服务名称：getGeoJSONByTxtInternalId
     功能描述：图形数据库中提取指定Txt文档的GeoJSON
     接口描述： /api/txt/getGeoJSONByTxtInternalId
     传入参数：
     long txtInternalId
     返回值：
     GeoJSON;
     调用示例：
     http://localhost:8090/api/txt/getGeoJSONByTxtInternalId?txtInternalId=3
     */
//    @GetMapping(value = "/txt/getGeoJSONByTxtInternalId")
//    public String getGeoJSONByTxtInternalId(
//            @RequestParam(value = "txtInternalId") long txtInternalId){
//        try {
//            TxtAll txtAll = txtService.getTxtByInternalId(BigDecimal.valueOf(txtInternalId));
//            if (txtAll==null) return new String();
//            return TxtExtractor.parseToGeoJSON(txtAll.getTxtRawBytes());
//        } catch (Exception e) {
//            throw new BaseException(e.getMessage());
//        }
//    }
}
